<script setup>
import {typeMap} from '../useForm';
import {computed, getCurrentInstance, ref, watch} from 'vue';
import FaIconInput from "./fa-icon-input.vue";
import FaRegionPicker from "./fa-region-picker.vue";
import FaDatetimePicker from "./fa-datetime-picker.vue";

const instance = getCurrentInstance();

defineOptions({
  options: {
    virtualHost: true,
  },
});

const props = defineProps({
  modelValue: Object,
  items: Array,
});

const formData = ref({});
const emits = defineEmits(['update:modelValue', 'choose', 'datetimeChange', 'areaChange', 'enterpriseChange']);
const currentItem = ref(undefined);

watch(() => props.modelValue, () => {
  formData.value = props.modelValue;
}, {
  immediate: true,
  deep: true,
});

watch(() => formData.value, () => {
  emits('update:modelValue', formData.value);
}, {
  deep: true,
});

const itemList = computed(() => {
  if (!props.items) return [];
  return props.items.map(item => {
    item.show = relItemShow(item);
    item.classList = relItemClass(item);
    item.elWrapperClassList = relElWrapperClass(item);
    // item.elAttrs = relElAttrs(item);
    item.attrs = relItemAttrs(item);
    return item;
  });
});

// 可显示的 formItem 的长度，用于判断是否显示底部边框
const showLen = computed(() => {
  const showList = itemList.value.filter(item => item.show);
  if (!showList) return 0;
  return showList.length;
});

function handleDatetimeChange(item, data) {
  emits('datetimeChange', item, data);
  // 关闭日期选择
  instance.refs[`datetimePicker${item.prop}Ref`][0].close();
}

function handleChoose(item) {
  emits('choose', item);
}

function handleChooseArea(item) {
  instance.refs[`regionPicker${item.prop}Ref`][0].open();
}

function handleAreaChange(item, info) {
  emits('areaChange', item, info);
  instance.refs[`regionPicker${item.prop}Ref`][0].close();
}

// 解析是否显示formItem中的元素
function relShow(item, type) {
  if (type instanceof Array) {
    if (!type.includes(item.type)) return false;
  } else if (item.type !== type) return false;
  return true;
}

// 解析是否显示formItem
function relItemShow(item) {
  if (!item) return false;
  if (item.showRender && typeof item.showRender === 'function') {
    return item.showRender(formData.value, item);
  }
  return true;
}

// 解析formItem的class
function relItemClass(item) {
  const classArr = [];
  if (item.customLabel) {
    classArr.push('custom-label');
    if (item.itemAttrs && item.itemAttrs.labelPosition) {
      classArr.push('custom-label-position-' + item.itemAttrs.labelPosition);
    }
  }
  const elAttrs = item.elAttrs;
  if (elAttrs) {
    if (elAttrs.textareaAlign) {
      classArr.push(`textarea-align-${elAttrs.textareaAlign}`);
    }
  }
  return classArr.join(' ');
}

// 解析formItem中组件容器的class
function relElWrapperClass(item) {
  const classArr = [];
  const elAttrs = item.elAttrs;
  if (elAttrs) {
    if (elAttrs.textareaAlign) {
      classArr.push(`textarea-align-${elAttrs.textareaAlign}`);
    }
  }
  return classArr.join(' ');
}

// 解析组件属性
function relElAttrs(item) {
  const attrs = {};
  const elAttrs = item.elAttrs;
  if (elAttrs && typeof elAttrs === 'object') {
    Object.assign(attrs, elAttrs);
  }
  const elAttrsRender = item.elAttrsRender;
  if (elAttrsRender && typeof elAttrsRender === 'function') {
    const attrsRes = elAttrsRender();
    Object.assign(attrs, attrsRes);
  }
  return attrs;
}

// 解析formItem属性
function relItemAttrs(item) {
  const attrs = {};
  const itemAttrs = item.itemAttrs;
  if (itemAttrs && typeof itemAttrs === 'object') {
    Object.assign(attrs, itemAttrs);
  }
  const itemAttrsRender = item.itemAttrsRender;
  if (itemAttrsRender && typeof itemAttrsRender === 'function') {
    const attrsRes = itemAttrsRender();
    Object.assign(attrs, attrsRes);
  }
  return attrs;
}

// 解析数字组件对齐方式
function relNumberStyle(item) {
  const style = {
    justifyContent: 'flex-start',
  };
  if (item.elAttrs) {
    if (item.elAttrs.numberAlign && item.elAttrs.numberAlign === 'right') {
      style.justifyContent = 'flex-end';
    }
  }
  return style;
}
</script>

<template>
  <view class="custom-form-item-list">
    <view
      class="custom-form-item"
      v-for="(item, index) in itemList"
      :key="item.prop"
      :class="[item.classList, {'last-item': index + 1 >= showLen}]">
      <slot :name="`${item.prop}Top`" :item="item"></slot>
      <view class="custom-form-item-container">
        <view class="custom-label" v-if="item.customLabel">
          <slot :name="`${item.prop}Label`" :item="item"></slot>
        </view>
        <up-form-item
          :label="item.label"
          :prop="item.prop"
          v-bind="item.attrs"
          v-if="item.show"
          :border-bottom="index + 1 < showLen">
          <view
            v-if="item.type !== 'custom'"
            class="form-item-el-wrapper"
            :class="[item.elWrapperClassList]">
            <up-input
              v-if="relShow(item, typeMap.INPUT)"
              v-model="formData[item.prop]"
              v-bind="relElAttrs(item)"></up-input>
            <up-input
              v-if="relShow(item, typeMap.INPUT_NUMBER)"
              v-model.number="formData[item.prop]"
              v-bind="relElAttrs(item)"></up-input>
            <up-textarea
              v-if="relShow(item, typeMap.TEXTAREA)"
              v-model="formData[item.prop]"
              v-bind="relElAttrs(item)"></up-textarea>
            <view
              class="form-item-flex"
              :style="relNumberStyle(item)"
              v-if="relShow(item, typeMap.NUMBER)">
              <up-number-box
                :name="item.prop"
                v-model="formData[item.prop]"
                v-bind="relElAttrs(item)"
                inputWidth="84rpx"
                bgColor="transparent"
                iconStyle="font-size: 20rpx;">
              </up-number-box>
            </view>
            <fa-icon-input
              v-else-if="relShow(item, typeMap.CHOOSE)"
              @click="handleChoose(item)"
              v-model="formData[item.prop]"
              v-bind="relElAttrs(item)">
              <template #suffix>
                <slot :name="`${item.prop}ChooseSuffix`"></slot>
              </template>
            </fa-icon-input>
            <template v-else-if="relShow(item, typeMap.AREA)">
              <fa-icon-input
                @click="handleChooseArea(item)"
                v-model="formData[item.prop]"
                v-bind="relElAttrs(item)">
              </fa-icon-input>
              <fa-region-picker
                :ref="`regionPicker${item.prop}Ref`"
                :model-value="item.valueRender ? item.valueRender(formData[item.prop], item) : []"
                @confirm="(info) => handleAreaChange(item, info)"
                v-bind="relElAttrs(item)"/>
            </template>
            <fa-datetime-picker
              v-else-if="relShow(item, [typeMap.DATETIME, typeMap.DATE, typeMap.TIME])"
              v-model="formData[item.prop]"
              :default-date="formData[item.prop]"
              :mode="item.type"
              :ref="`datetimePicker${item.prop}Ref`"
              @confirm="(data) => handleDatetimeChange(item, data)"
              v-bind="relElAttrs(item)">
            </fa-datetime-picker>
          </view>
          <template v-if="item.type === 'custom'">
            <slot :name="item.prop" :item="item"></slot>
          </template>
        </up-form-item>
      </view>
      <up-line v-if="item.customLabel && item.itemAttrs && item.itemAttrs.borderBottom"></up-line>
      <slot :name="`${item.prop}Bottom`" :item="item"></slot>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.form-item-el-wrapper {
  width: 100%;
}

.form-item-flex {
  width: 100%;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
}


// 自定义表单样式，下面的样式如果无效，放入全局样式中
.custom-form-item {
  // 自定义表单隐藏 label，用于自定义 label
  &.custom-label {

    & > .custom-form-item-container {
      // 自定义表单 label 时，flex 布局
      display: flex;
      flex-direction: row;
      box-sizing: border-box;

      & > .u-form-item {
        flex: 1;
        padding: 0;

        & > .u-form-item__body {
          & > .u-form-item__body__left {
            display: none;
          }
        }

        // form校验提示
        & > .u-form-item__body__right__message {
          margin-bottom: 5px;
        }

        & > .u-line {
          display: none;
        }
      }
    }

    // label 位置为 top 时
    &.custom-label-position-top {
      & > .custom-form-item-container {
        flex-direction: column;
      }
    }
  }

  // 最后的 formItem
  &.last-item {
    & > .custom-form-item-container {
      & > .u-form-item {
        // form校验提示
        & > .u-form-item__body__right__message {
          margin-bottom: 5px;
        }
      }
    }
  }

  .form-item-el-wrapper {
    // 文本域居右
    &.textarea-align-right {
      .u-textarea textarea {
        text-align: right;
      }
    }
  }
}
</style>
